audit: bead/mcb-o96i-16-hook-commit-recovery-v3 -> main - #166
audit: bead/mcb-o96i-16-hook-commit-recovery-v3 -> main#166marlon-costa-dc wants to merge 10 commits into
Conversation
|
Caution The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased. |
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Recoverable checkpoint of in-flight work. Not a delivery; gates deferred. Origin branch: bead/mcb-o96i-16-hook-commit-recovery-v3
There was a problem hiding this comment.
17 issues found across 14 files
Confidence score: 2/5
- In
scripts/lib/mcb.sh, the staged-check path forCargo.toml/Cargo.lockbuilds an invalidcargo fmtinvocation (--workspacein the wrong position), so commits that touch manifests/lockfiles can fail the gate outright — adjust the fmt command construction so workspace checks use supported Cargo fmt argument ordering. scripts/lib/mcb.shcurrently validates working-tree state instead of the staged snapshot, and package derivation skips manifest/build/non-srctarget changes, so broken staged Rust can slip through pre-commit and regress CI/mainline quality — run checks against an index materialization (or fail on staged/unstaged divergence) and include those crate paths in package selection.- Submodule sync behavior in
scripts/lib/mcb.shis brittle:make sub WHAT=synccan hang forever on POSIX/bin/shdue toread -d, and partially materialized submodules may be treated as complete, leaving tracked files missing — switch to a POSIX-safe reader (or explicitly invoke Bash) and verify/restore missing indexed paths file-by-file. - Workspace command tooling has multiple reliability gaps across
scripts/lib/workspace_command.pyandscripts/lib/workspace.py: missingtomlcauses dispatcher import failure, empty shim env vars can add.toPATH, and help/dry-run/validation errors may exit without user-visible guidance — provision the runtime dependency, treat empty shim overrides as unset, and always print rendered help/error output before returning.
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="scripts/hooks/pre-commit">
<violation number="1" location="scripts/hooks/pre-commit:10">
P3: Published pre-commit instructions still promise lint and architecture validation; update them to describe the staged-only gate so developers do not rely on checks this hook no longer runs.</violation>
</file>
<file name="Makefile">
<violation number="1" location="Makefile:39">
P3: The new check phases (staged/hooks/guard) are not reflected in AGENTS.md/README.md, which still list check WHAT as fmt|lint|validate|audit|udeps|coverage|qlty|all. Since those docs are embedded as agent/reviewer context, updating them keeps the documented surface in sync with the fact that the phases already work here.</violation>
</file>
<file name="scripts/lib/workspace.py">
<violation number="1" location="scripts/lib/workspace.py:19">
P2: An explicitly empty `WORKSPACE_MISE_SHIMS`/`MISE_SHIMS` adds `.` to dispatched-command `PATH`, allowing executables in the working tree to shadow system tools. Treat empty overrides as unset before constructing the `Path`.</violation>
</file>
<file name="scripts/lib/workspace_command.py">
<violation number="1" location="scripts/lib/workspace_command.py:20">
P1: Every dispatcher invocation fails at import when its required `toml` package is not preinstalled; declare and provision this runtime dependency for the workspace Python environment.</violation>
<violation number="2" location="scripts/lib/workspace_command.py:185">
P2: Help, action options, and mutation dry-runs exit successfully without displaying any guidance because every corresponding branch returns before emitting its `render_*` result. Print the appropriate rendered text before these returns.</violation>
<violation number="3" location="scripts/lib/workspace_command.py:185">
P3: This statement is a no-op: it calls `os.environ.get("WHAT", "").strip()` and discards the result. It looks like a leftover line from an earlier help-rendering draft, and the very next line returns 0, so this has zero effect. Safe to delete.</violation>
<violation number="4" location="scripts/lib/workspace_command.py:188">
P2: Invalid invocations fail with exit code 2 but no diagnostic, hiding required parameters and metadata errors; print the caught `RegistryError` to stderr before returning.</violation>
<violation number="5" location="scripts/lib/workspace_command.py:205">
P2: The dry-run path for mutating commands returns 0 with no user-facing feedback, and the dedicated `render_dry_run()` helper defined at line 616 is never called anywhere in the module. The advertised framework behavior ("Dry-run: sem APPLY=Y, o dispatcher nao executa a acao" plus the render_dry_run DRY-RUN banner) is disconnected from the execution path: a user running a mutating command without `APPLY=Y` sees no indication that nothing was executed. Either emit `render_dry_run(...)` on this branch, or remove the never-referenced rendering helpers.</violation>
<violation number="6" location="scripts/lib/workspace_command.py:360">
P2: Malformed marked command headers can be silently excluded from validation because `has_header` treats parse errors like an absent header. Return false only for the explicit no-header case and propagate malformed-header errors.</violation>
</file>
<file name="scripts/lib/tests/test-hooks.sh">
<violation number="1" location="scripts/lib/tests/test-hooks.sh:71">
P3: The `timeout` stub's `*[smhd]` pattern swallows any argument ending in s/m/h/d, not only the duration token. It only works because `cargo` is always the first word after the timeout options, so consider narrowing the match to duration-shaped args (e.g. `*[0-9][smhd]`) so a future reorder or option doesn't silently drop a real argument and skew the log assertions.</violation>
</file>
<file name="scripts/hooks/pre-push">
<violation number="1" location="scripts/hooks/pre-push:1">
P3: The new pre-push source file is committed without the executable bit (mode 644), unlike scripts/hooks/pre-commit (755). The installer chmods the installed copy so the primary path works, but any direct execution of the in-tree hook (e.g. core.hooksPath pointing at scripts/hooks, or invoking it manually/from CI) silently fails; set the executable bit on the committed file to match pre-commit.</violation>
</file>
<file name="scripts/lib/mcb.sh">
<violation number="1" location="scripts/lib/mcb.sh:59">
P2: Repositories with `core.hooksPath` configured install hooks into the unused default directory, leaving the advertised pre-commit enforcement inactive; resolve and honor the configured hooks path before copying.</violation>
<violation number="2" location="scripts/lib/mcb.sh:81">
P1: `make sub WHAT=sync` loops forever on POSIX `/bin/sh` systems because `git submodule foreach` cannot execute Bash's `read -d`; use a POSIX-compatible path reader or explicitly invoke Bash for this pipeline.</violation>
<violation number="3" location="scripts/lib/mcb.sh:82">
P1: A submodule with one remaining tracked file is treated as materialized, so `sync-submodules` leaves other deleted tracked files missing; check every indexed path and restore only missing paths to preserve local edits.</violation>
<violation number="4" location="scripts/lib/mcb.sh:137">
P1: Commits that stage Cargo.toml/Cargo.lock will fail the staged check. When a manifest/lockfile is staged, `packages` is set to `--workspace` and fed to `cargo fmt $packages -- --check`, but `cargo fmt` does not accept `--workspace` (only `-p/--package` and `--all`), so it exits 2 and the pre-commit gate aborts. `cargo clippy` does accept `--workspace`, which is why the mismatch only surfaces on the fmt call. Use a scope flag that both tools accept (e.g. `--all`) or split fmt/clippy scoping.</violation>
<violation number="5" location="scripts/lib/mcb.sh:141">
P2: Manifest, build-script, and non-`src` target changes skip the staged fmt/clippy gate entirely; include those crate paths when deriving `packages` so `--all-targets` covers the staged change.</violation>
<violation number="6" location="scripts/lib/mcb.sh:155">
P1: The pre-commit gate validates unstaged working-tree contents rather than the staged snapshot, allowing invalid staged Rust to pass after an unstaged local fix; run checks against an index materialization or reject relevant unstaged changes.</violation>
</file>
Shadow auto-approve: would not auto-approve because issues were found.
Re-trigger cubic
| from pathlib import Path | ||
| from typing import NoReturn | ||
|
|
||
| import toml |
There was a problem hiding this comment.
P1: Every dispatcher invocation fails at import when its required toml package is not preinstalled; declare and provision this runtime dependency for the workspace Python environment.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At scripts/lib/workspace_command.py, line 20:
<comment>Every dispatcher invocation fails at import when its required `toml` package is not preinstalled; declare and provision this runtime dependency for the workspace Python environment.</comment>
<file context>
@@ -0,0 +1,778 @@
+from pathlib import Path
+from typing import NoReturn
+
+import toml
+
+from lib.workspace import (
</file context>
| [ -n "$staged" ] || { mcb_ok "staged check: no staged paths"; return 0; } | ||
|
|
||
| if printf '%s\n' "$staged" | grep -qE '^Cargo\.(toml|lock)$'; then | ||
| packages="--workspace" |
There was a problem hiding this comment.
P1: Commits that stage Cargo.toml/Cargo.lock will fail the staged check. When a manifest/lockfile is staged, packages is set to --workspace and fed to cargo fmt $packages -- --check, but cargo fmt does not accept --workspace (only -p/--package and --all), so it exits 2 and the pre-commit gate aborts. cargo clippy does accept --workspace, which is why the mismatch only surfaces on the fmt call. Use a scope flag that both tools accept (e.g. --all) or split fmt/clippy scoping.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At scripts/lib/mcb.sh, line 137:
<comment>Commits that stage Cargo.toml/Cargo.lock will fail the staged check. When a manifest/lockfile is staged, `packages` is set to `--workspace` and fed to `cargo fmt $packages -- --check`, but `cargo fmt` does not accept `--workspace` (only `-p/--package` and `--all`), so it exits 2 and the pre-commit gate aborts. `cargo clippy` does accept `--workspace`, which is why the mismatch only surfaces on the fmt call. Use a scope flag that both tools accept (e.g. `--all`) or split fmt/clippy scoping.</comment>
<file context>
@@ -77,6 +125,38 @@ mcb_validate() { # $1 = "quick" | "full"
+ [ -n "$staged" ] || { mcb_ok "staged check: no staged paths"; return 0; }
+
+ if printf '%s\n' "$staged" | grep -qE '^Cargo\.(toml|lock)$'; then
+ packages="--workspace"
+ else
+ while IFS= read -r path; do
</file context>
|
|
||
| [ -n "$packages" ] || { mcb_ok "staged check: no Rust package affected"; return 0; } | ||
| mcb_log "staged check: cargo fmt/clippy scope:$packages (deadline ${deadline}s each)" | ||
| timeout --signal=TERM --kill-after=5s "${deadline}s" cargo fmt $packages -- --check |
There was a problem hiding this comment.
P1: The pre-commit gate validates unstaged working-tree contents rather than the staged snapshot, allowing invalid staged Rust to pass after an unstaged local fix; run checks against an index materialization or reject relevant unstaged changes.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At scripts/lib/mcb.sh, line 155:
<comment>The pre-commit gate validates unstaged working-tree contents rather than the staged snapshot, allowing invalid staged Rust to pass after an unstaged local fix; run checks against an index materialization or reject relevant unstaged changes.</comment>
<file context>
@@ -77,6 +125,38 @@ mcb_validate() { # $1 = "quick" | "full"
+
+ [ -n "$packages" ] || { mcb_ok "staged check: no Rust package affected"; return 0; }
+ mcb_log "staged check: cargo fmt/clippy scope:$packages (deadline ${deadline}s each)"
+ timeout --signal=TERM --kill-after=5s "${deadline}s" cargo fmt $packages -- --check
+ timeout --signal=TERM --kill-after=5s "${deadline}s" cargo clippy $packages --all-targets -- -D warnings
+ mcb_ok "staged check: clean"
</file context>
| present="$(git ls-files -z | while IFS= read -r -d "" path; do | ||
| if [ -e "$path" ] || [ -L "$path" ]; then | ||
| printf 1 | ||
| break | ||
| fi | ||
| done)" |
There was a problem hiding this comment.
P1: make sub WHAT=sync loops forever on POSIX /bin/sh systems because git submodule foreach cannot execute Bash's read -d; use a POSIX-compatible path reader or explicitly invoke Bash for this pipeline.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At scripts/lib/mcb.sh, line 81:
<comment>`make sub WHAT=sync` loops forever on POSIX `/bin/sh` systems because `git submodule foreach` cannot execute Bash's `read -d`; use a POSIX-compatible path reader or explicitly invoke Bash for this pipeline.</comment>
<file context>
@@ -51,6 +51,54 @@ mcb_retry() { local n="$1" s="$2"; shift 2; local t=1; while ! "$@"; do [ "$t" -
+
+ while :; do
+ materialized="$(git -C "$repo" submodule foreach --quiet --recursive '
+ present="$(git ls-files -z | while IFS= read -r -d "" path; do
+ if [ -e "$path" ] || [ -L "$path" ]; then
+ printf 1
</file context>
| present="$(git ls-files -z | while IFS= read -r -d "" path; do | |
| if [ -e "$path" ] || [ -L "$path" ]; then | |
| printf 1 | |
| break | |
| fi | |
| done)" | |
| present="$(git ls-files | while IFS= read -r path; do | |
| if [ -e "$path" ] || [ -L "$path" ]; then | |
| printf 1 | |
| break | |
| fi | |
| done)" |
| while :; do | ||
| materialized="$(git -C "$repo" submodule foreach --quiet --recursive ' | ||
| present="$(git ls-files -z | while IFS= read -r -d "" path; do | ||
| if [ -e "$path" ] || [ -L "$path" ]; then |
There was a problem hiding this comment.
P1: A submodule with one remaining tracked file is treated as materialized, so sync-submodules leaves other deleted tracked files missing; check every indexed path and restore only missing paths to preserve local edits.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At scripts/lib/mcb.sh, line 82:
<comment>A submodule with one remaining tracked file is treated as materialized, so `sync-submodules` leaves other deleted tracked files missing; check every indexed path and restore only missing paths to preserve local edits.</comment>
<file context>
@@ -51,6 +51,54 @@ mcb_retry() { local n="$1" s="$2"; shift 2; local t=1; while ! "$@"; do [ "$t" -
+ while :; do
+ materialized="$(git -C "$repo" submodule foreach --quiet --recursive '
+ present="$(git ls-files -z | while IFS= read -r -d "" path; do
+ if [ -e "$path" ] || [ -L "$path" ]; then
+ printf 1
+ break
</file context>
| echo "→ guard (staged)…"; bash scripts/lib/mcb.sh guard --staged | ||
| echo "→ lint…"; make check WHAT=lint | ||
| echo "→ validate (quick)…"; make check WHAT=validate QUICK=1 | ||
| echo "→ staged check…"; make check WHAT=staged |
There was a problem hiding this comment.
P3: Published pre-commit instructions still promise lint and architecture validation; update them to describe the staged-only gate so developers do not rely on checks this hook no longer runs.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At scripts/hooks/pre-commit, line 10:
<comment>Published pre-commit instructions still promise lint and architecture validation; update them to describe the staged-only gate so developers do not rely on checks this hook no longer runs.</comment>
<file context>
@@ -1,11 +1,11 @@
echo "→ guard (staged)…"; bash scripts/lib/mcb.sh guard --staged
-echo "→ lint…"; make check WHAT=lint
-echo "→ validate (quick)…"; make check WHAT=validate QUICK=1
+echo "→ staged check…"; make check WHAT=staged
echo "✓ pre-commit passed"
</file context>
|
|
||
| # --- WHATS_<verb> phase SSOT (drives sub-help + error arms) ------------------- | ||
| WHATS_check := fmt lint validate audit udeps coverage qlty all | ||
| WHATS_check := fmt lint staged validate audit udeps coverage qlty hooks guard all |
There was a problem hiding this comment.
P3: The new check phases (staged/hooks/guard) are not reflected in AGENTS.md/README.md, which still list check WHAT as fmt|lint|validate|audit|udeps|coverage|qlty|all. Since those docs are embedded as agent/reviewer context, updating them keeps the documented surface in sync with the fact that the phases already work here.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At Makefile, line 39:
<comment>The new check phases (staged/hooks/guard) are not reflected in AGENTS.md/README.md, which still list check WHAT as fmt|lint|validate|audit|udeps|coverage|qlty|all. Since those docs are embedded as agent/reviewer context, updating them keeps the documented surface in sync with the fact that the phases already work here.</comment>
<file context>
@@ -36,7 +36,7 @@ export RUST_2024_LINTS := -D unsafe_op_in_unsafe_fn -D rust_2024_compatibility -
# --- WHATS_<verb> phase SSOT (drives sub-help + error arms) -------------------
-WHATS_check := fmt lint validate audit udeps coverage qlty all
+WHATS_check := fmt lint staged validate audit udeps coverage qlty hooks guard all
WHATS_fix := fmt lint docs all
WHATS_dev := run docker-up docker-down docker-logs docker-test
</file context>
| #!/usr/bin/env bash | ||
| while [ "$#" -gt 0 ]; do | ||
| case "$1" in | ||
| --signal=*|--kill-after=*|*[smhd]) shift ;; |
There was a problem hiding this comment.
P3: The timeout stub's *[smhd] pattern swallows any argument ending in s/m/h/d, not only the duration token. It only works because cargo is always the first word after the timeout options, so consider narrowing the match to duration-shaped args (e.g. *[0-9][smhd]) so a future reorder or option doesn't silently drop a real argument and skew the log assertions.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At scripts/lib/tests/test-hooks.sh, line 71:
<comment>The `timeout` stub's `*[smhd]` pattern swallows any argument ending in s/m/h/d, not only the duration token. It only works because `cargo` is always the first word after the timeout options, so consider narrowing the match to duration-shaped args (e.g. `*[0-9][smhd]`) so a future reorder or option doesn't silently drop a real argument and skew the log assertions.</comment>
<file context>
@@ -0,0 +1,130 @@
+#!/usr/bin/env bash
+while [ "$#" -gt 0 ]; do
+ case "$1" in
+ --signal=*|--kill-after=*|*[smhd]) shift ;;
+ *) break ;;
+ esac
</file context>
| @@ -0,0 +1,10 @@ | |||
| #!/usr/bin/env bash | |||
There was a problem hiding this comment.
P3: The new pre-push source file is committed without the executable bit (mode 644), unlike scripts/hooks/pre-commit (755). The installer chmods the installed copy so the primary path works, but any direct execution of the in-tree hook (e.g. core.hooksPath pointing at scripts/hooks, or invoking it manually/from CI) silently fails; set the executable bit on the committed file to match pre-commit.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At scripts/hooks/pre-push, line 1:
<comment>The new pre-push source file is committed without the executable bit (mode 644), unlike scripts/hooks/pre-commit (755). The installer chmods the installed copy so the primary path works, but any direct execution of the in-tree hook (e.g. core.hooksPath pointing at scripts/hooks, or invoking it manually/from CI) silently fails; set the executable bit on the committed file to match pre-commit.</comment>
<file context>
@@ -0,0 +1,10 @@
+#!/usr/bin/env bash
+# Installed by `make setup WHAT=hooks`. Runs the canonical full gate before
+# push, then preserves Beads hook processing when available.
</file context>
| if args and args[0] == "--validate": | ||
| return 0 | ||
| if not args or args[0] in {"help", "--help", "-h"}: | ||
| os.environ.get("WHAT", "").strip() |
There was a problem hiding this comment.
P3: This statement is a no-op: it calls os.environ.get("WHAT", "").strip() and discards the result. It looks like a leftover line from an earlier help-rendering draft, and the very next line returns 0, so this has zero effect. Safe to delete.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At scripts/lib/workspace_command.py, line 185:
<comment>This statement is a no-op: it calls `os.environ.get("WHAT", "").strip()` and discards the result. It looks like a leftover line from an earlier help-rendering draft, and the very next line returns 0, so this has zero effect. Safe to delete.</comment>
<file context>
@@ -0,0 +1,778 @@
+ if args and args[0] == "--validate":
+ return 0
+ if not args or args[0] in {"help", "--help", "-h"}:
+ os.environ.get("WHAT", "").strip()
+ return 0
+ return dispatch(registry, args[0])
</file context>
There was a problem hiding this comment.
0 issues found across 1 file (changes from recent commits).
Confidence score: 5/5
- Automated review surfaced no issues in the provided summaries.
- No files require special attention.
Shadow auto-approve: would not auto-approve. Auto-approval blocked by 17 unresolved issues from previous reviews.
Re-trigger cubic
|
Closed: associated bead already resolved via recovery lane (21c9d7f). Branch work was absorbed or superseded. |
GitFlow audit verdict (automated 2026-08-02)
main: 9 commits | behind: 136origin/main: clean/home/marlonsc/mcb/.worktrees/mcb-o96i-16-hook-commit-recovery-v3Verdict: KEEP-OPEN for review — pushed by gitflow audit; not auto-merged per policy.